﻿using System.Reflection;
using WeDonekRpc.ApiGateway.Interface;
using WeDonekRpc.Client;
using WeDonekRpc.Client.Attr;
using WeDonekRpc.Helper;
using WeDonekRpc.HttpApiGateway.Collect;
using WeDonekRpc.HttpApiGateway.Config;
using WeDonekRpc.HttpApiGateway.Interface;
using WeDonekRpc.HttpApiGateway.Service;

namespace WeDonekRpc.HttpApiGateway
{
    /// <summary>
    /// 模块的基类
    /// </summary>
    public class BasicApiModular : IApiModular
    {
        private HttpGatewayOption _Option;
        private readonly ModularConfig _Config;
        private readonly Client.Interface.IIocService _Ioc;
        private string[] _Filters = null;
        public BasicApiModular ( string name, string show = null )
        {
            this._Config = new ModularConfig();
            this.ServiceName = name;
            this._Ioc = RpcClient.Ioc;
            this.Route = new ModularRouteService(this);
            this.Show = show;
        }

        public IModularConfig Config => this._Config;
        public string ServiceName
        {
            get;
        }
        public bool IsInit { get; private set; } = false;

        public string ApiRouteFormat => this._Config.ApiRouteFormat;

        public IModularRouteService Route { get; }
        public string Show { get; }

        public void Load ( IGatewayOption option )
        {
            ApiModularCollect.RegModular(this);
            this._Option = new HttpGatewayOption(option, this);
            this.Load(this._Option, this._Config);
            this._Option.Load();
        }

        public void InitModular ()
        {
            this._Option.Init();
            this._Option = null;
            this.IsInit = true;
            this.Init();
        }

        protected virtual void Load ( IHttpGatewayOption option, IModularConfig config )
        {

        }
        protected virtual void Init ()
        {

        }

        public void Start ()
        {
        }

        public void Dispose ()
        {
        }

        public virtual void InitRouteConfig ( IApiModel config )
        {

        }

        public void AddFilters<T> () where T : IApiRouteFilter
        {
            IocName name = typeof(T).GetCustomAttribute<IocName>();
            if ( name == null )
            {
                throw new ErrorException("gateway.ioc.name.null");
            }
            this.AddFilters<T>(name.Name);
        }
        public void AddFilters<T> ( int index ) where T : IApiRouteFilter
        {
            IocName name = typeof(T).GetCustomAttribute<IocName>();
            if ( name == null )
            {
                throw new ErrorException("gateway.ioc.name.null");
            }
            this.AddFilters<T>(name.Name, index);
        }
        public void AddFilters<T> ( string iocName ) where T : IApiRouteFilter
        {
            this._Filters = this._Filters.Add(iocName);
        }

        public void AddFilters<T> ( string iocName, int index ) where T : IApiRouteFilter
        {
            if ( this._Filters == null )
            {
                this._Filters = new string[] { iocName };
            }
            else
            {
                this._Filters = this._Filters.Insert(iocName, index);
            }
        }

        public void Begin ( IApiService service, IRoute route )
        {
            if ( !this._Filters.IsNull() )
            {
                foreach ( string i in this._Filters )
                {
                    IApiRouteFilter filter = this._Ioc.Resolve<IApiRouteFilter>(i);
                    filter.BeginRequest(service, route);
                }
            }
        }

        public void End ( IApiService service, IRoute route )
        {
            if ( !this._Filters.IsNull() )
            {
                foreach ( string i in this._Filters )
                {
                    IApiRouteFilter filter = this._Ioc.Resolve<IApiRouteFilter>(i);
                    filter.EndRequest(service, route);
                }
            }
        }
    }
}
